#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
MCP Client Gateway - 将 fastmcp 客户端封装为 HTTP API 服务
"""

import os
import asyncio
from typing import Dict, Any
from fastapi import FastAPI, HTTPException, Body
from fastmcp import Client

# ========== 配置区域 ==========
# 默认 MCP Server 地址（可通过环境变量覆盖）
MCP_SERVER_URL = os.getenv("MCP_SERVER_URL", "http://192.168.0.254:8000/mcp")

# 初始化 FastAPI 应用
app = FastAPI(
    title="MCP Client Gateway",
    description="通过 HTTP API 调用远程 MCP 服务",
    version="1.0.0"
)

# 创建 MCP 客户端实例
client = Client(MCP_SERVER_URL)


# ========== 生命周期事件 ==========
@app.on_event("startup")
async def startup_event():
    """服务启动时自动连接 MCP Server"""
    try:
        await client.__aenter__()
        await client.ping()
        print(f"✅ 已成功连接 MCP Server: {MCP_SERVER_URL}")
    except Exception as e:
        print(f"❌ 无法连接 MCP Server: {e}")
        raise e


@app.on_event("shutdown")
async def shutdown_event():
    """关闭时断开连接"""
    await client.__aexit__(None, None, None)


# ========== HTTP API 路由 ==========

@app.get("/")
async def root():
    return {
        "service": "MCP Client Gateway",
        "status": "running",
        "server": MCP_SERVER_URL,
        "endpoints": ["/ping", "/tools", "/resources", "/prompts", "/call_tool"]
    }


@app.get("/ping")
async def ping():
    """测试与 MCP Server 的连接状态"""
    try:
        await client.ping()
        return {"status": "ok", "server": MCP_SERVER_URL}
    except Exception as e:
        raise HTTPException(status_code=500, detail=str(e))


@app.get("/tools")
async def list_tools():
    """获取 MCP Server 暴露的工具列表"""
    try:
        tools = await client.list_tools()
        return {"tools": [t.model_dump() for t in tools]}
    except Exception as e:
        raise HTTPException(status_code=500, detail=str(e))


@app.get("/resources")
async def list_resources():
    """获取 MCP Server 的资源列表"""
    try:
        resources = await client.list_resources()
        return {"resources": [r.model_dump() for r in resources]}
    except Exception as e:
        raise HTTPException(status_code=500, detail=str(e))


@app.get("/prompts")
async def list_prompts():
    """获取 MCP Server 的 prompt 模板列表"""
    try:
        prompts = await client.list_prompts()
        return {"prompts": [p.model_dump() for p in prompts]}
    except Exception as e:
        raise HTTPException(status_code=500, detail=str(e))


@app.post("/call_tool")
async def call_tool(
    tool_name: str = Body(..., embed=True, description="工具名称"),
    params: Dict[str, Any] = Body({}, embed=True, description="工具参数")
):
    """
    调用远程 MCP 工具

    请求示例：
    POST /call_tool
    {
        "tool_name": "weather_mcp_server_get_weather",
        "params": {"input_str": "上海"}
    }
    """
    try:
        result = await client.call_tool(tool_name, params)
        return {"tool": tool_name, "result": result}
    except Exception as e:
        raise HTTPException(status_code=500, detail=str(e))


# ========== 主入口 ==========
if __name__ == "__main__":
    import uvicorn
    port = int(os.getenv("PORT", 7125))
    print(f"🚀 MCP Client Gateway 启动中: http://0.0.0.0:{port}")
    print(f"🌐 连接到远程 MCP Server: {MCP_SERVER_URL}")
    uvicorn.run("mcp_client_gateway:app", host="0.0.0.0", port=port, reload=False)
